package top.hmtools.security;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * SHA1算法工具类
 * @author Jianghaibo
 *
 */
public class SHA1Tools {
    
    /**
     * 获取输入流的SHA1加密值，结果为英文字母小写
     * <br>20180315 通过了与Apache Commons codec 的计算结果比对
    * <br>方法说明：                    getLowSHA1Str
    * <br>输入参数说明：           
    * <br>@param inputStream
    * <br>@return
    * <br>输出参数说明：
    * <br>String           
    *
     */
    public final static String getLowSHA1Str(InputStream inputStream) {
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
            byte[] buffer = new byte[8192];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                messageDigest.update(buffer, 0, length);
            }
            BigInteger bi = new BigInteger(1, messageDigest.digest()); 
            return bi.toString(16).toLowerCase();
        } catch (Exception e) {
            return null;
        }finally{
            try {
                if (inputStream != null)
                    inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 获取文件的SHA1加密值，结果为英文字母小写
     *  <br>20180315 通过了与Apache Commons codec 的计算结果比对
    * <br>方法说明：                    getLowSHA1Str
    * <br>输入参数说明：           
    * <br>@param file
    * <br>@return
    * <br>输出参数说明：
    * <br>String           
    *
     */
    public final static String getLowSHA1Str(File file) {
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            return getLowSHA1Str(fileInputStream);
        } catch (FileNotFoundException e) {
            return null;
        }
    }

    /**
     *  获得 字节数组 的SHA1加密值，结果为英文字母小写
     *  <br>20180315 通过了与Apache Commons codec 的计算结果比对
    * <br>方法说明：                    getLowSHA1Str
    * <br>输入参数说明：           
    * <br>@param bytes
    * <br>@return
    * <br>@throws NoSuchAlgorithmException
    * <br>输出参数说明：
    * <br>String           
    *
     */
    public final static String getLowSHA1Str(byte[] bytes) {
        MessageDigest messageDigest = null;
        try {
            messageDigest = MessageDigest.getInstance("SHA1");
        } catch (NoSuchAlgorithmException e) {
            return null;
        }  
        messageDigest.update(bytes); 
        byte[] resultBytes = messageDigest.digest();
     // 获得密文
        BigInteger bi = new BigInteger(1, resultBytes); 
        return bi.toString(16).toLowerCase();
    }
    
    /**
     * 获得 字符串（指定字符编码） 的SHA1加密值，结果为英文字母小写
     * <br>20180315 通过了与Apache Commons codec 的计算结果比对
    * <br>方法说明：                    getLowSHA1Str
    * <br>输入参数说明：           
    * <br>@param str
    * <br>@param charset
    * <br>@return
    * <br>@throws NoSuchAlgorithmException
    * <br>输出参数说明：
    * <br>String           
    *
     */
    public final static String getLowSHA1Str(String str,Charset charset) {
        return getLowSHA1Str(str.getBytes(charset));
    }
    
    /**
     *  获得 字符串 的SHA1加密值，结果为英文字母小写
     *  <br>20180315 通过了与Apache Commons codec 的计算结果比对
    * <br>方法说明：                    getLowSHA1Str
    * <br>输入参数说明：           
    * <br>@param str
    * <br>@return
    * <br>@throws NoSuchAlgorithmException
    * <br>输出参数说明：
    * <br>String           
    *
     */
    public final static String getLowSHA1Str(String str) {
        return getLowSHA1Str(str.getBytes());
    }
}
